#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<assert.h>
#include<cmath>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int inf=1000000000;

#define maxn  1010
#define maxe 1000*210
int n,m;
int p,q;
int g[maxn][1100];
/****************多重匹配模板*********************/
int first[maxn],next[maxe],E[maxe],M;
void insert(int a,int b)
{
	M++;
	next[M]=first[a];
	first[a]=M;
	E[M]=b;
}

void init()
{
	M=-1;
	memset(first,-1,sizeof(first));
}

int fl[maxn], match[maxn][maxn],vis[maxn];//match[y][x]要特别注意左边的是y的大小，右边的是x的大小,fl是y的多重匹配可选最多的点，vis是标记y是否被访问国
bool can(int x)
{
	int y,i,e,j;
	for(e=first[x]; e!=-1; e=next[e])
	{
		y=E[e];
		if(!vis[y])
		{
			vis[y]=1;
			if(match[y][0]<fl[y])
			{
				match[y][++match[y][0]]=x;
				return true;
			}
			else
			{
				for(j=1; j<=fl[y]; j++)
					if(can(match[y][j]))
					{
						match[y][j]=x;
						return true;
					}
			}
		}
	}
	return false;
}

int hungarian(int n,int m)//n是x的点数，m是y的点数
{//x是从1到n，y是可以从1到m 
	int f=0,i;
	for(i=0; i<=m; i++)
		match[i][0]=0;
	for(i=1; i<=n; i++)
	{
		memset(vis,0,sizeof(vis));
		if(can(i))	f++;
	}
	return f;
}

/****************多重匹配模板*********************/
bool ok(int l,int r)
{
	p=l,q=r;
	int i,j;
	init();
	for(i=1; i<=n ;i++)
	for(j=1; j<=m; j++)
	if(p<=g[i][j] && g[i][j]<=q )
	{
		insert(i,j);
	}
	
	int w=hungarian(n,m);
	if(w==n)
		return true;
	return false;
}

int main()
{
//	freopen("in","r",stdin);
    int i,j,k;
	while(scanf("%d%d", &n,&m)!=EOF)
	{
		memset(g,0,sizeof(g));
			init();
		for(i=1; i<=n ;i++)
		for(j=1; j<=m; j++)
		{
			scanf("%d",&k);
			g[i][k]=j;
		}
		for(i=1; i<=m; i++)
			scanf("%d", &fl[i]);
		int l=1,r=1, ans=m;
		while(l<=r && r<=m )
		{
			if(ok(l,r))
			{
				ans=min(r-l+1,ans);
				l++;
			}
			else
				r++;
		}
		printf("%d\n",ans);
	}
	return 0;
}
